﻿using System;
using System.Collections.Generic;
using System.Text;
using Workflow.Entity;
using System.Collections;
using Workflow.Interface;
using MyLib;
using System.Web;
using System.Data;


namespace Workflow.Logic
{
    public class UltimusTaskLogic : ITask
    {
        //string GetTasks()
        //{
        //    string archiveDBName = ConfigurationManager.AppSettings["ArchiveDBName"];
        //    if (!string.IsNullOrEmpty(archiveDBName))
        //    {
        //        //return " (SELECT * FROM TASKS UNION ALL SELECT * FROM " + archiveDBName + "..TASKS) ";
        //        return "TASKS";
        //    }
        //    else
        //    {
        //        return "TASKS";
        //    }
        //}
        //string GetIncidents()
        //{
        //    string archiveDBName = ConfigurationManager.AppSettings["ArchiveDBName"];
        //    if (!string.IsNullOrEmpty(archiveDBName))
        //    {
        //        //return " (SELECT * FROM INCIDENTS UNION ALL SELECT * FROM " + archiveDBName + "..INCIDENTS) ";
        //        return "INCIDENTS";
        //    }
        //    else
        //    {
        //        return "INCIDENTS";
        //    }
        //}

        public virtual List<TaskEntity> GetMyTask(string filter, Hashtable table, string sort, int skipResults, int maxResults)
        {
            if (table == null)
            {
                table = new Hashtable();
            }
            table.Add("filter", filter);
            table.Add("Sort", sort);
            //table.Add("TASKS", GetTasks());
            //table.Add("INCIDENTS", GetIncidents());
            return DataAccess.Instance("BizDB").GetList<TaskEntity>("TaskLogic_GetMyTask", table, skipResults, maxResults);
        }

        public virtual int GetMyTaskCount(string filter, Hashtable table)
        {
            if (table == null)
            {
                table = new Hashtable();
            }
            table.Add("filter", filter);
            //table.Add("TASKS", GetTasks());
            //table.Add("INCIDENTS", GetIncidents());
            return ConvertUtil.ToInt32(DataAccess.Instance("BizDB").GetObject("TaskLogic_GetMyTaskCount", table));
        }

        public virtual List<TaskEntity> GetMyApproval(string filter, Hashtable table, string sort, int skipResults, int maxResults)
        {
            if (table == null)
            {
                table = new Hashtable();
            }
            table.Add("filter", filter);
            table.Add("Sort", sort);
            //table.Add("TASKS", GetTasks());
            //table.Add("INCIDENTS", GetIncidents());
            return DataAccess.Instance("BizDB").GetList<TaskEntity>("TaskLogic_GetMyApproval", table, skipResults, maxResults);
        }

        public virtual int GetMyApprovalCount(string filter, Hashtable table)
        {
            if (table == null)
            {
                table = new Hashtable();
            }
            table.Add("filter", filter);
            //table.Add("TASKS", GetTasks());
            //table.Add("INCIDENTS", GetIncidents());
            return ConvertUtil.ToInt32(DataAccess.Instance("BizDB").GetObject("TaskLogic_GetMyApprovalCount", table));
        }

        public virtual List<TaskEntity> GetMyRequest(string filter, Hashtable table, string sort, int skipResults, int maxResults)
        {
            if (table == null)
            {
                table = new Hashtable();
            }
            table.Add("filter", filter);
            table.Add("Sort", sort);
            //table.Add("TASKS", GetTasks());
            //table.Add("INCIDENTS", GetIncidents());
            return DataAccess.Instance("BizDB").GetList<TaskEntity>("TaskLogic_GetMyRequest", table, skipResults, maxResults);
        }

        public virtual int GetMyRequestCount(string filter, Hashtable table)
        {
            if (table == null)
            {
                table = new Hashtable();
            }
            table.Add("filter", filter);
            //table.Add("TASKS", GetTasks());
            //table.Add("INCIDENTS", GetIncidents());
            return ConvertUtil.ToInt32(DataAccess.Instance("BizDB").GetObject("TaskLogic_GetMyRequestCount", table));
        }


        public virtual TaskEntity GetEntity(string taskID)
        {
            Hashtable table = new Hashtable();
            //table.Add("TASKS", GetTasks());
            table.Add("taskID", taskID);
            return DataAccess.Instance("BizDB").GetEntity<TaskEntity>("TaskLogic_GetEntity", table);
        }

        public virtual TaskEntity GetStartEntity(string taskID)
        {
            return DataAccess.Instance("UltDB").GetEntity<TaskEntity>("TaskLogic_GetStartEntity", taskID);
        }

        public void InsertBackFromArchive(string processName, int incident)
        {
            string archiveDBName = ConfigurationManager.AppSettings["ArchiveDBName"];
            if (!string.IsNullOrEmpty(archiveDBName))
            {
                Hashtable table = new Hashtable();
                table.Add("processName", processName);
                table.Add("incident", incident);
                table.Add("ArchiveDBName", archiveDBName);
                if (DataAccess.Instance("UltDB").SqlMapper.DataSource.DbProvider.Name.ToUpper().IndexOf("ORACLE") >= 0)
                {
                    DataAccess.Instance("UltDB").Insert("TaskLogic_InsertBackFromArchiveOracle", table);
                }
                else
                {
                    DataAccess.Instance("UltDB").Insert("TaskLogic_InsertBackFromArchive", table);
                }
            }
        }

        public virtual string GetTaskUrl(string taskID, string type, string userName)
        {
            TaskEntity entity = new TaskEntity();
            if (taskID.StartsWith("S"))
            {
                entity = GetStartEntity(taskID);
            }
            else
            {
                entity = GetEntity(taskID);
            }
            string processName = "";
            string stepLabel = "";
            int incident;
            if (entity == null)
            {
                Ultimus.WFServer.Task task = new Ultimus.WFServer.Task();
                task.InitializeFromTaskId(taskID);
                processName = task.strProcessName.Trim();
                stepLabel = task.strStepName.Trim();
                incident = task.nIncidentNo;
            }
            else
            {
                processName = entity.PROCESSNAME.Trim();
                stepLabel = entity.STEPLABEL.Trim();
                incident = entity.INCIDENT;
            }

            string page = StepSettingsLogic.GetStepPage(processName, stepLabel);
            string url = "";
            if (string.IsNullOrEmpty(page)) //Standard Form
            {
                string result = "";
                Ultimus.WFServer.Task t = new Ultimus.WFServer.Task();
                t.InitializeFromTaskId(taskID);
                t.ExtractFormURL(out result);
                if (!string.IsNullOrEmpty(result))
                {
                    string ServerName = HttpContext.Current.Request.Url.Host;
                    //if (result.StartsWith("."))
                    //{
                    //    result = result.Replace("./", "");
                    //}
                    //url = ConvertUtil.ToString(MyLib.ConfigurationManager.AppSettings["StandardClientUrl"]) + result;
                    //HttpContext.Current.Response.AddHeader("Ultimus Workflow1", "Ultimus Workflow");
                    //HttpContext.Current.Response.Cookies["TaskID"].Value = taskID;
                    //HttpContext.Current.Response.Cookies["TaskID"].Path = @"/";
                    //HttpContext.Current.Response.Cookies["UserID"].Value = userName;
                    //HttpContext.Current.Response.Cookies["UserID"].Path = @"/";
                    //string ServerName = HttpContext.Current.Request.Url.Host;

                    url = "http://" + ServerName + "/Ultweb/" + result;
                    //url = ConvertUtil.ToString(MyLib.ConfigurationManager.AppSettings["StandardClientUrl"]) + result;
                    HttpContext.Current.Response.AddHeader("Ultimus Workflow1", "Ultimus Workflow");
                    HttpContext.Current.Response.Cookies["TaskID"].Value = taskID;
                    HttpContext.Current.Response.Cookies["TaskID"].Path = @"/";
                    HttpContext.Current.Response.Cookies["UserID"].Value = userName;
                    HttpContext.Current.Response.Cookies["UserID"].Path = @"/";
                }
                else
                {
                    if (entity != null) //有这个task,把该task再插入回来
                    {
                        InsertBackFromArchive(entity.PROCESSNAME, entity.INCIDENT);
                        t.InitializeFromTaskId(taskID);
                        t.ExtractFormURL(out result);
                        if (!string.IsNullOrEmpty(result))
                        {
                            if (result.StartsWith("."))
                            {
                                result = result.Replace("./", "");
                            }
                            string ServerName = HttpContext.Current.Request.Url.Host;

                            url = "http://" + ServerName + "/Ultweb/" + result;
                            //url = ConvertUtil.ToString(MyLib.ConfigurationManager.AppSettings["StandardClientUrl"]) + result;
                            HttpContext.Current.Response.AddHeader("Ultimus Workflow1", "Ultimus Workflow");
                            HttpContext.Current.Response.Cookies["TaskID"].Value = taskID;
                            HttpContext.Current.Response.Cookies["TaskID"].Path = @"/";
                            HttpContext.Current.Response.Cookies["UserID"].Value = userName;
                            HttpContext.Current.Response.Cookies["UserID"].Path = @"/";
                        }
                    }
                    else
                    {
                        throw new Exception(Workflow.Resources.lang.OpenForm_CannotLoadTask);
                    }
                }
            }
            else //.net Form
            {
                url = "http://" + HttpContext.Current.Request.Url.Host + ":"
                    + HttpContext.Current.Request.Url.Port + "/" + page + "?ProcessName=" + processName + "&StepName=" + stepLabel + "&Incident="
                   + incident + "&TaskID=" + taskID + "&UserName=" + HttpContext.Current.Server.UrlEncode(userName) + "&Type=" + type;
            }
            return url;
        }

        public virtual Hashtable LoadTask(string taskId)
        {
            Ultimus.WFServer.Task task = new Ultimus.WFServer.Task();
            bool flag = task.InitializeFromTaskId(taskId);
            Hashtable table = new Hashtable();
            if (flag)
            {
                Ultimus.WFServer.Variable[] vs;
                string strError = "";
                task.GetAllTaskVariables(out vs, out strError);
                if (vs == null)
                {
                    return table;
                }
                foreach (Ultimus.WFServer.Variable var in vs)
                {
                    if (var.objVariableValue != null && var.objVariableValue.Length > 0)
                    {
                        table.Add(var.strVariableName, var.objVariableValue[0]);
                    }
                }
            }
            return table;
        }

        public virtual Ultimus.WFServer.Variable[] GetVariables(Hashtable vars, string taskid, string username)
        {
            if (vars == null)
            {
                return null;
            }
            if (username.IndexOf("D") > 0)
            {
                username = vars["ApplicantAccount"].ToString();
            }

            Ultimus.WFServer.Task tsk = new Ultimus.WFServer.Task();
            bool bInitflag = true;
            if (taskid.StartsWith("S"))
            {
                bInitflag = tsk.InitializeFromInitiateTaskId(username, taskid);
            }
            else
            {
                bInitflag = tsk.InitializeFromTaskId(taskid);
            }

            if (!bInitflag)
            {
                throw new Exception("方法GetVariables中初始化Task对象失败。");
            }
            int i = 0;
            Ultimus.WFServer.Variable[] vTaskVarList = null;
            string strError = "";
            tsk.GetAllTaskVariables(out vTaskVarList, out strError);


            Ultimus.WFServer.Variable[] vs = new Ultimus.WFServer.Variable[vTaskVarList.Length];
            foreach (string str in vars.Keys)
            {
                // vTaskVarList.
                bool bflag = false;
                for (int j = 0; j < vTaskVarList.Length; j++)
                {
                    Ultimus.WFServer.Variable vTask = vTaskVarList[j];
                    if (vTask.strVariableName.Trim().ToLower() == str.Trim().ToLower())
                    {
                        bflag = true;
                    }
                }
                if (bflag)
                {
                    Ultimus.WFServer.Variable pvar = new Ultimus.WFServer.Variable();
                    pvar.strVariableName = str;
                    object value = vars[str];

                    //-----------------------------modify by Sky 判断是否数组变量 2013-6-7 18:42W
                    if (value.GetType().FullName == "System.String[]")
                    {
                        pvar.objVariableValue = value as object[];
                    }
                    else if (value.ToString().Contains("|USER"))
                    {
                        object[] objVal = null;
                        string strValue = value.ToString().Replace("|USER", "");
                        if (strValue.Contains("<+>"))
                        {
                            string[] strVals = strValue.Replace("<", "").Replace(">", "").Split(new char[] { '+' });
                            if (strVals.Length > 5)
                                objVal = strVals;
                            else
                            {
                                string[] strNew = new string[5];
                                strVals.CopyTo(strNew, 0);
                                objVal = strVals;
                            }
                        }
                        else
                        {
                            objVal = new object[5];
                            objVal[0] = strValue;
                        }
                        pvar.objVariableValue = objVal;
                    }
                    else
                    {
                        pvar.objVariableValue = new object[] { value };
                    }
                    //------------ ----------------------------
                    vs[i] = pvar;
                    i++;
                }
            }
            return vs;
        }

        /// <summary>
        /// 提交任务
        /// </summary>
        /// <param name="userName">任务所属的用户名</param>
        /// <param name="taskId">任务ID</param>
        /// <param name="vars">电子表格变量</param>
        /// <param name="sync">true:同步 false:异步</param>
        /// <returns>同步>0的流程实例号 同步=0 失败 异步：-1</returns>
        public virtual string SubmitTask(string userName, string taskId, string summary, Hashtable vars, bool sync, ref int incident)
        {
            Ultimus.WFServer.Task task = new Ultimus.WFServer.Task();
            bool flag = task.InitializeFromTaskId(taskId);
            string strError = "";
            try
            {
                if (flag)
                {
                    // vars["ApplicantAccount"]
                    Ultimus.WFServer.Variable[] vs = GetVariables(vars, taskId, userName);
                    if (!sync)
                    {
                        incident = -1;
                    }
                    if (!task.SendFrom(userName.Replace("\\", "/"), vs, "", summary, ref incident, out strError))
                    {
                        if (string.IsNullOrEmpty(strError) || incident == 0)
                        {
                            strError = "请稍候从草稿箱打开，重新提交！";
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                strError = ex.Message;
            }
            return strError;
        }

        public virtual string ReturnTask(string userName, string taskId, string reason, string summary, Hashtable vars, bool sync)
        {
            Ultimus.WFServer.Task task = new Ultimus.WFServer.Task();
            bool flag = task.InitializeFromTaskId(taskId);
            string strError = "";
            if (flag)
            {
                Ultimus.WFServer.Variable[] vs = GetVariables(vars, taskId, userName);
                task.Return(vs, reason, summary, out strError);

            }
            return strError;
        }

        public virtual string RejectTask(string userName, string taskId, string reason, Hashtable vars, bool sync)
        {
            return AbortProcess(userName, taskId, reason, vars, sync);
        }

        public virtual string AbortProcess(string userName, string taskId, string reason, Hashtable vars, bool sync)
        {
            Ultimus.WFServer.Task task = new Ultimus.WFServer.Task();
            bool flag = task.InitializeFromTaskId(taskId);
            userName = userName.Replace("\\", "/");
            string strError = "";
            if (flag)
            {
                Ultimus.WFServer.Incident incident = new Ultimus.WFServer.Incident();
                incident.LoadIncident(task.strProcessName, task.nIncidentNo);
                incident.AbortIncident(userName, reason, out strError);
            }
            return strError;
        }


        public virtual List<ProcessEntity> GetInitProcessList(string userName)
        {

            List<ProcessEntity> initProcessList = new List<ProcessEntity>();
            //load init process
            Ultimus.WFServer.TasklistFilter filter = new Ultimus.WFServer.TasklistFilter();
            filter.strArrUserName = new string[1] { userName };
            Ultimus.WFServer.Tasklist tl = new Ultimus.WFServer.Tasklist();
            filter.nFiltersMask = Ultimus.WFServer.Filters.nFilter_Initiate;
            tl.LoadFilteredTasks(filter);
            for (int i = 0; i < tl.GetTasksCount(); i++)
            {
                ProcessEntity process = new ProcessEntity();
                process.PROCESSNAME = tl.GetAt(i).strProcessName;
                process.INITIATEID = tl.GetAt(i).strTaskId;
                initProcessList.Add(process);
            }
            return initProcessList;
        }
        public virtual string GetCurrentUser(string strProcess, int incident)
        {
            string strSql = "select b.FirstName from v_tasks a  " +
                                "inner join v_employee b on b.ShortName = rtrim(a.ASSIGNEDTOUSER) " +
                                    "where a.PROCESSNAME='" + strProcess.Trim() + "'and a.INCIDENT='" + incident + "' and a.STATUS = 1 ";
            System.Data.DataTable dt = DataAccess.Instance("BizDB").ExecuteDataTable(strSql);
            if (dt.Rows.Count > 0)
            {
                string rtnVal = "";
                foreach (DataRow dr in dt.Rows)
                {
                    rtnVal += ConvertUtil.ToString(dr[0]) + ",";
                }
                return rtnVal.TrimEnd(new char[] { ',' });
            }
            return "";
        }


        public virtual bool AbortIncident(string taskId, out string strError)
        {
            strError = "";
            try
            {
                Ultimus.WFServer.Task tsk = new Ultimus.WFServer.Task();
                tsk.InitializeFromTaskId(taskId);

                //初始话Incident
                Ultimus.WFServer.Incident inc = new Ultimus.WFServer.Incident();
                inc.LoadIncident(tsk.strProcessName, tsk.nIncidentNo);
                Ultimus.WFServer.Incident.Status iStatus = new Ultimus.WFServer.Incident.Status();
                inc.GetIncidentStatus(out iStatus);
                if (iStatus.nIncidentStatus == Ultimus.WFServer.IncidentStatuses.INCIDENT_STATUS_ACTIVE ||
                    iStatus.nIncidentStatus == Ultimus.WFServer.IncidentStatuses.INCIDENT_STATUS_PENDING)
                {
                    inc.SetVariableValue("Disable Abort", true, out strError);
                    //inc.LoadIncident(tsk.strProcessName, tsk.nIncidentNo);
                    return inc.AbortIncident(inc.strIncidentOwner, "用户Portal取消", out strError);
                }
                else
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                strError = strError + ex.Message;
                return false;
            }

        }
    }
}
